## serpent.py - pure Python implementation of the Serpent algorithm.

import binascii
import base64

block_size = 16
key_size = 32


class Serpent:

    def __init__(self, key=None):
        """Serpent."""

        if key:
            self.set_key(key)

    def set_key(self, key):
        """Init."""

        key_len = len(key)
        if key_len % 4:
            # XXX: add padding?
            raise KeyError("key not a multiple of 4")
        if key_len > 32:
            # XXX: prune?
            raise KeyError("key_len > 32")

        self.key_context = [0] * 140

        key_word32 = [0] * 32
        i = 0
        while key:
            key_word32[i] = struct.unpack("<L", key[0:4])[0]
            key = key[4:]
            i += 1

        set_key(self.key_context, key_word32, key_len)
        # print(map(hex,self.key_context))

    def decrypt(self, block):
        """Decrypt blocks."""

        if len(block) % 16:
            raise ValueError("block size must be a multiple of 16")

        plaintext = b''

        while block:
            a, b, c, d = struct.unpack("<4L", block[:16])
            temp = [a, b, c, d]
            decrypt(self.key_context, temp)
            plaintext += struct.pack("<4L", *temp)
            block = block[16:]

        return plaintext

    def encrypt(self, block):
        """Encrypt blocks."""

        if len(block) % 16:
            raise ValueError("block size must be a multiple of 16")

        ciphertext = b''

        while block:
            a, b, c, d = struct.unpack("<4L", block[0:16])
            temp = [a, b, c, d]
            encrypt(self.key_context, temp)
            ciphertext += struct.pack("<4L", *temp)
            block = block[16:]

        return ciphertext

    def get_name(self):
        """Return the name of the cipher."""

        return "Serpent"

    def get_block_size(self):
        """Get cipher block size in bytes."""

        return 16

    def get_key_size(self):
        """Get cipher key size in bytes."""

        return 32


#
# Private.
#

import struct
import sys

WORD_BIGENDIAN = 0
if sys.byteorder == 'big':
    WORD_BIGENDIAN = 1


def rotr32(x, n):
    return (x >> n) | ((x << (32 - n)) & 0xFFFFFFFF)


def rotl32(x, n):
    return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))


def byteswap32(x):
    return ((x & 0xff) << 24) | (((x >> 8) & 0xff) << 16) | \
           (((x >> 16) & 0xff) << 8) | ((x >> 24) & 0xff)


def set_key(l_key, key, key_len):
    key_len *= 8
    if key_len > 256:
        return False

    i = 0
    lk = (key_len + 31) / 32
    while i < lk:
        l_key[i] = key[i]
        if WORD_BIGENDIAN:
            l_key[i] = byteswap32(key[i])
        i += 1

    if key_len < 256:
        while i < 8:
            l_key[i] = 0
            i += 1
        i = key_len // 32
        lk = 1 << (key_len % 32)
        l_key[i] = (l_key[i] & (lk - 1)) | lk
    for i in range(132):
        lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] ^ l_key[i + 7] ^ 0x9e3779b9 ^ i
        l_key[i + 8] = ((lk << 11) & 0xFFFFFFFF) | (lk >> 21)

    key = l_key
    # serpent_generate.py
    a = key[4 * 0 + 8]
    b = key[4 * 0 + 9]
    c = key[4 * 0 + 10]
    d = key[4 * 0 + 11]
    e = 0
    f = 0
    g = 0
    h = 0
    t1 = 0
    t2 = 0
    t3 = 0
    t4 = 0
    t5 = 0
    t6 = 0
    t7 = 0
    t8 = 0
    t9 = 0
    t10 = 0
    t11 = 0
    t12 = 0
    t13 = 0
    t14 = 0
    t15 = 0
    t16 = 0
    t1 = a ^ c;
    t2 = d ^ t1;
    t3 = a & t2;
    t4 = d ^ t3;
    t5 = b & t4;
    g = t2 ^ t5;
    t7 = a | g;
    t8 = b | d;
    t11 = a | d;
    t9 = t4 & t7;
    f = t8 ^ t9;
    t12 = b ^ t11;
    t13 = g ^ t9;
    t15 = t3 ^ t8;
    h = t12 ^ t13;
    t16 = c & t15;
    e = t12 ^ t16
    key[4 * 0 + 8] = e
    key[4 * 0 + 9] = f
    key[4 * 0 + 10] = g
    key[4 * 0 + 11] = h
    a = key[4 * 1 + 8]
    b = key[4 * 1 + 9]
    c = key[4 * 1 + 10]
    d = key[4 * 1 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    key[4 * 1 + 8] = e
    key[4 * 1 + 9] = f
    key[4 * 1 + 10] = g
    key[4 * 1 + 11] = h
    a = key[4 * 2 + 8]
    b = key[4 * 2 + 9]
    c = key[4 * 2 + 10]
    d = key[4 * 2 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ t1;
    t3 = a | t2;
    t4 = d | t2;
    t5 = c ^ t3;
    g = d ^ t5;
    t7 = b ^ t4;
    t8 = t2 ^ g;
    t9 = t5 & t7;
    h = t8 ^ t9;
    t11 = t5 ^ t7;
    f = h ^ t11;
    t13 = t8 & t11;
    e = t5 ^ t13
    key[4 * 2 + 8] = e
    key[4 * 2 + 9] = f
    key[4 * 2 + 10] = g
    key[4 * 2 + 11] = h
    a = key[4 * 3 + 8]
    b = key[4 * 3 + 9]
    c = key[4 * 3 + 10]
    d = key[4 * 3 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    key[4 * 3 + 8] = e
    key[4 * 3 + 9] = f
    key[4 * 3 + 10] = g
    key[4 * 3 + 11] = h
    a = key[4 * 4 + 8]
    b = key[4 * 4 + 9]
    c = key[4 * 4 + 10]
    d = key[4 * 4 + 11]
    t1 = (~c) % 0x100000000;
    t2 = b ^ c;
    t3 = b | t1;
    t4 = d ^ t3;
    t5 = a & t4;
    t7 = a ^ d;
    h = t2 ^ t5;
    t8 = b ^ t5;
    t9 = t2 | t8;
    t11 = d & t3;
    f = t7 ^ t9;
    t12 = t5 ^ f;
    t15 = t1 | t4;
    t13 = h & t12;
    g = t11 ^ t13;
    t16 = t12 ^ g;
    e = t15 ^ t16
    key[4 * 4 + 8] = e
    key[4 * 4 + 9] = f
    key[4 * 4 + 10] = g
    key[4 * 4 + 11] = h
    a = key[4 * 5 + 8]
    b = key[4 * 5 + 9]
    c = key[4 * 5 + 10]
    d = key[4 * 5 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    key[4 * 5 + 8] = e
    key[4 * 5 + 9] = f
    key[4 * 5 + 10] = g
    key[4 * 5 + 11] = h
    a = key[4 * 6 + 8]
    b = key[4 * 6 + 9]
    c = key[4 * 6 + 10]
    d = key[4 * 6 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ b;
    t3 = a ^ d;
    t4 = c ^ t1;
    t5 = t2 | t3;
    e = t4 ^ t5;
    t7 = d & e;
    t8 = t2 ^ e;
    t10 = t1 | e;
    f = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = b ^ t7;
    g = t11 ^ t12;
    t15 = f & t12;
    h = t14 ^ t15
    key[4 * 6 + 8] = e
    key[4 * 6 + 9] = f
    key[4 * 6 + 10] = g
    key[4 * 6 + 11] = h
    a = key[4 * 7 + 8]
    b = key[4 * 7 + 9]
    c = key[4 * 7 + 10]
    d = key[4 * 7 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    key[4 * 7 + 8] = e
    key[4 * 7 + 9] = f
    key[4 * 7 + 10] = g
    key[4 * 7 + 11] = h
    a = key[4 * 8 + 8]
    b = key[4 * 8 + 9]
    c = key[4 * 8 + 10]
    d = key[4 * 8 + 11]
    t1 = a ^ c;
    t2 = d ^ t1;
    t3 = a & t2;
    t4 = d ^ t3;
    t5 = b & t4;
    g = t2 ^ t5;
    t7 = a | g;
    t8 = b | d;
    t11 = a | d;
    t9 = t4 & t7;
    f = t8 ^ t9;
    t12 = b ^ t11;
    t13 = g ^ t9;
    t15 = t3 ^ t8;
    h = t12 ^ t13;
    t16 = c & t15;
    e = t12 ^ t16
    key[4 * 8 + 8] = e
    key[4 * 8 + 9] = f
    key[4 * 8 + 10] = g
    key[4 * 8 + 11] = h
    a = key[4 * 9 + 8]
    b = key[4 * 9 + 9]
    c = key[4 * 9 + 10]
    d = key[4 * 9 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    key[4 * 9 + 8] = e
    key[4 * 9 + 9] = f
    key[4 * 9 + 10] = g
    key[4 * 9 + 11] = h
    a = key[4 * 10 + 8]
    b = key[4 * 10 + 9]
    c = key[4 * 10 + 10]
    d = key[4 * 10 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ t1;
    t3 = a | t2;
    t4 = d | t2;
    t5 = c ^ t3;
    g = d ^ t5;
    t7 = b ^ t4;
    t8 = t2 ^ g;
    t9 = t5 & t7;
    h = t8 ^ t9;
    t11 = t5 ^ t7;
    f = h ^ t11;
    t13 = t8 & t11;
    e = t5 ^ t13
    key[4 * 10 + 8] = e
    key[4 * 10 + 9] = f
    key[4 * 10 + 10] = g
    key[4 * 10 + 11] = h
    a = key[4 * 11 + 8]
    b = key[4 * 11 + 9]
    c = key[4 * 11 + 10]
    d = key[4 * 11 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    key[4 * 11 + 8] = e
    key[4 * 11 + 9] = f
    key[4 * 11 + 10] = g
    key[4 * 11 + 11] = h
    a = key[4 * 12 + 8]
    b = key[4 * 12 + 9]
    c = key[4 * 12 + 10]
    d = key[4 * 12 + 11]
    t1 = (~c) % 0x100000000;
    t2 = b ^ c;
    t3 = b | t1;
    t4 = d ^ t3;
    t5 = a & t4;
    t7 = a ^ d;
    h = t2 ^ t5;
    t8 = b ^ t5;
    t9 = t2 | t8;
    t11 = d & t3;
    f = t7 ^ t9;
    t12 = t5 ^ f;
    t15 = t1 | t4;
    t13 = h & t12;
    g = t11 ^ t13;
    t16 = t12 ^ g;
    e = t15 ^ t16
    key[4 * 12 + 8] = e
    key[4 * 12 + 9] = f
    key[4 * 12 + 10] = g
    key[4 * 12 + 11] = h
    a = key[4 * 13 + 8]
    b = key[4 * 13 + 9]
    c = key[4 * 13 + 10]
    d = key[4 * 13 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    key[4 * 13 + 8] = e
    key[4 * 13 + 9] = f
    key[4 * 13 + 10] = g
    key[4 * 13 + 11] = h
    a = key[4 * 14 + 8]
    b = key[4 * 14 + 9]
    c = key[4 * 14 + 10]
    d = key[4 * 14 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ b;
    t3 = a ^ d;
    t4 = c ^ t1;
    t5 = t2 | t3;
    e = t4 ^ t5;
    t7 = d & e;
    t8 = t2 ^ e;
    t10 = t1 | e;
    f = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = b ^ t7;
    g = t11 ^ t12;
    t15 = f & t12;
    h = t14 ^ t15
    key[4 * 14 + 8] = e
    key[4 * 14 + 9] = f
    key[4 * 14 + 10] = g
    key[4 * 14 + 11] = h
    a = key[4 * 15 + 8]
    b = key[4 * 15 + 9]
    c = key[4 * 15 + 10]
    d = key[4 * 15 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    key[4 * 15 + 8] = e
    key[4 * 15 + 9] = f
    key[4 * 15 + 10] = g
    key[4 * 15 + 11] = h
    a = key[4 * 16 + 8]
    b = key[4 * 16 + 9]
    c = key[4 * 16 + 10]
    d = key[4 * 16 + 11]
    t1 = a ^ c;
    t2 = d ^ t1;
    t3 = a & t2;
    t4 = d ^ t3;
    t5 = b & t4;
    g = t2 ^ t5;
    t7 = a | g;
    t8 = b | d;
    t11 = a | d;
    t9 = t4 & t7;
    f = t8 ^ t9;
    t12 = b ^ t11;
    t13 = g ^ t9;
    t15 = t3 ^ t8;
    h = t12 ^ t13;
    t16 = c & t15;
    e = t12 ^ t16
    key[4 * 16 + 8] = e
    key[4 * 16 + 9] = f
    key[4 * 16 + 10] = g
    key[4 * 16 + 11] = h
    a = key[4 * 17 + 8]
    b = key[4 * 17 + 9]
    c = key[4 * 17 + 10]
    d = key[4 * 17 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    key[4 * 17 + 8] = e
    key[4 * 17 + 9] = f
    key[4 * 17 + 10] = g
    key[4 * 17 + 11] = h
    a = key[4 * 18 + 8]
    b = key[4 * 18 + 9]
    c = key[4 * 18 + 10]
    d = key[4 * 18 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ t1;
    t3 = a | t2;
    t4 = d | t2;
    t5 = c ^ t3;
    g = d ^ t5;
    t7 = b ^ t4;
    t8 = t2 ^ g;
    t9 = t5 & t7;
    h = t8 ^ t9;
    t11 = t5 ^ t7;
    f = h ^ t11;
    t13 = t8 & t11;
    e = t5 ^ t13
    key[4 * 18 + 8] = e
    key[4 * 18 + 9] = f
    key[4 * 18 + 10] = g
    key[4 * 18 + 11] = h
    a = key[4 * 19 + 8]
    b = key[4 * 19 + 9]
    c = key[4 * 19 + 10]
    d = key[4 * 19 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    key[4 * 19 + 8] = e
    key[4 * 19 + 9] = f
    key[4 * 19 + 10] = g
    key[4 * 19 + 11] = h
    a = key[4 * 20 + 8]
    b = key[4 * 20 + 9]
    c = key[4 * 20 + 10]
    d = key[4 * 20 + 11]
    t1 = (~c) % 0x100000000;
    t2 = b ^ c;
    t3 = b | t1;
    t4 = d ^ t3;
    t5 = a & t4;
    t7 = a ^ d;
    h = t2 ^ t5;
    t8 = b ^ t5;
    t9 = t2 | t8;
    t11 = d & t3;
    f = t7 ^ t9;
    t12 = t5 ^ f;
    t15 = t1 | t4;
    t13 = h & t12;
    g = t11 ^ t13;
    t16 = t12 ^ g;
    e = t15 ^ t16
    key[4 * 20 + 8] = e
    key[4 * 20 + 9] = f
    key[4 * 20 + 10] = g
    key[4 * 20 + 11] = h
    a = key[4 * 21 + 8]
    b = key[4 * 21 + 9]
    c = key[4 * 21 + 10]
    d = key[4 * 21 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    key[4 * 21 + 8] = e
    key[4 * 21 + 9] = f
    key[4 * 21 + 10] = g
    key[4 * 21 + 11] = h
    a = key[4 * 22 + 8]
    b = key[4 * 22 + 9]
    c = key[4 * 22 + 10]
    d = key[4 * 22 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ b;
    t3 = a ^ d;
    t4 = c ^ t1;
    t5 = t2 | t3;
    e = t4 ^ t5;
    t7 = d & e;
    t8 = t2 ^ e;
    t10 = t1 | e;
    f = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = b ^ t7;
    g = t11 ^ t12;
    t15 = f & t12;
    h = t14 ^ t15
    key[4 * 22 + 8] = e
    key[4 * 22 + 9] = f
    key[4 * 22 + 10] = g
    key[4 * 22 + 11] = h
    a = key[4 * 23 + 8]
    b = key[4 * 23 + 9]
    c = key[4 * 23 + 10]
    d = key[4 * 23 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    key[4 * 23 + 8] = e
    key[4 * 23 + 9] = f
    key[4 * 23 + 10] = g
    key[4 * 23 + 11] = h
    a = key[4 * 24 + 8]
    b = key[4 * 24 + 9]
    c = key[4 * 24 + 10]
    d = key[4 * 24 + 11]
    t1 = a ^ c;
    t2 = d ^ t1;
    t3 = a & t2;
    t4 = d ^ t3;
    t5 = b & t4;
    g = t2 ^ t5;
    t7 = a | g;
    t8 = b | d;
    t11 = a | d;
    t9 = t4 & t7;
    f = t8 ^ t9;
    t12 = b ^ t11;
    t13 = g ^ t9;
    t15 = t3 ^ t8;
    h = t12 ^ t13;
    t16 = c & t15;
    e = t12 ^ t16
    key[4 * 24 + 8] = e
    key[4 * 24 + 9] = f
    key[4 * 24 + 10] = g
    key[4 * 24 + 11] = h
    a = key[4 * 25 + 8]
    b = key[4 * 25 + 9]
    c = key[4 * 25 + 10]
    d = key[4 * 25 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    key[4 * 25 + 8] = e
    key[4 * 25 + 9] = f
    key[4 * 25 + 10] = g
    key[4 * 25 + 11] = h
    a = key[4 * 26 + 8]
    b = key[4 * 26 + 9]
    c = key[4 * 26 + 10]
    d = key[4 * 26 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ t1;
    t3 = a | t2;
    t4 = d | t2;
    t5 = c ^ t3;
    g = d ^ t5;
    t7 = b ^ t4;
    t8 = t2 ^ g;
    t9 = t5 & t7;
    h = t8 ^ t9;
    t11 = t5 ^ t7;
    f = h ^ t11;
    t13 = t8 & t11;
    e = t5 ^ t13
    key[4 * 26 + 8] = e
    key[4 * 26 + 9] = f
    key[4 * 26 + 10] = g
    key[4 * 26 + 11] = h
    a = key[4 * 27 + 8]
    b = key[4 * 27 + 9]
    c = key[4 * 27 + 10]
    d = key[4 * 27 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    key[4 * 27 + 8] = e
    key[4 * 27 + 9] = f
    key[4 * 27 + 10] = g
    key[4 * 27 + 11] = h
    a = key[4 * 28 + 8]
    b = key[4 * 28 + 9]
    c = key[4 * 28 + 10]
    d = key[4 * 28 + 11]
    t1 = (~c) % 0x100000000;
    t2 = b ^ c;
    t3 = b | t1;
    t4 = d ^ t3;
    t5 = a & t4;
    t7 = a ^ d;
    h = t2 ^ t5;
    t8 = b ^ t5;
    t9 = t2 | t8;
    t11 = d & t3;
    f = t7 ^ t9;
    t12 = t5 ^ f;
    t15 = t1 | t4;
    t13 = h & t12;
    g = t11 ^ t13;
    t16 = t12 ^ g;
    e = t15 ^ t16
    key[4 * 28 + 8] = e
    key[4 * 28 + 9] = f
    key[4 * 28 + 10] = g
    key[4 * 28 + 11] = h
    a = key[4 * 29 + 8]
    b = key[4 * 29 + 9]
    c = key[4 * 29 + 10]
    d = key[4 * 29 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    key[4 * 29 + 8] = e
    key[4 * 29 + 9] = f
    key[4 * 29 + 10] = g
    key[4 * 29 + 11] = h
    a = key[4 * 30 + 8]
    b = key[4 * 30 + 9]
    c = key[4 * 30 + 10]
    d = key[4 * 30 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ b;
    t3 = a ^ d;
    t4 = c ^ t1;
    t5 = t2 | t3;
    e = t4 ^ t5;
    t7 = d & e;
    t8 = t2 ^ e;
    t10 = t1 | e;
    f = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = b ^ t7;
    g = t11 ^ t12;
    t15 = f & t12;
    h = t14 ^ t15
    key[4 * 30 + 8] = e
    key[4 * 30 + 9] = f
    key[4 * 30 + 10] = g
    key[4 * 30 + 11] = h
    a = key[4 * 31 + 8]
    b = key[4 * 31 + 9]
    c = key[4 * 31 + 10]
    d = key[4 * 31 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    key[4 * 31 + 8] = e
    key[4 * 31 + 9] = f
    key[4 * 31 + 10] = g
    key[4 * 31 + 11] = h
    a = key[4 * 32 + 8]
    b = key[4 * 32 + 9]
    c = key[4 * 32 + 10]
    d = key[4 * 32 + 11]
    t1 = a ^ c;
    t2 = d ^ t1;
    t3 = a & t2;
    t4 = d ^ t3;
    t5 = b & t4;
    g = t2 ^ t5;
    t7 = a | g;
    t8 = b | d;
    t11 = a | d;
    t9 = t4 & t7;
    f = t8 ^ t9;
    t12 = b ^ t11;
    t13 = g ^ t9;
    t15 = t3 ^ t8;
    h = t12 ^ t13;
    t16 = c & t15;
    e = t12 ^ t16
    key[4 * 32 + 8] = e
    key[4 * 32 + 9] = f
    key[4 * 32 + 10] = g
    key[4 * 32 + 11] = h


def encrypt(key, in_blk):
    # serpent_generate.py
    a = in_blk[0]
    b = in_blk[1]
    c = in_blk[2]
    d = in_blk[3]
    if WORD_BIGENDIAN:
        a = byteswap32(a)
        b = byteswap32(b)
        c = byteswap32(c)
        d = byteswap32(d)
    e = 0
    f = 0
    g = 0
    h = 0
    t1 = 0
    t2 = 0
    t3 = 0
    t4 = 0
    t5 = 0
    t6 = 0
    t7 = 0
    t8 = 0
    t9 = 0
    t10 = 0
    t11 = 0
    t12 = 0
    t13 = 0
    t14 = 0
    t15 = 0
    t16 = 0
    a ^= key[4 * 0 + 8]
    b ^= key[4 * 0 + 9]
    c ^= key[4 * 0 + 10]
    d ^= key[4 * 0 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 1 + 8]
    f ^= key[4 * 1 + 9]
    g ^= key[4 * 1 + 10]
    h ^= key[4 * 1 + 11]
    t1 = (~e) % 0x100000000;
    t2 = f ^ t1;
    t3 = e | t2;
    t4 = h | t2;
    t5 = g ^ t3;
    c = h ^ t5;
    t7 = f ^ t4;
    t8 = t2 ^ c;
    t9 = t5 & t7;
    d = t8 ^ t9;
    t11 = t5 ^ t7;
    b = d ^ t11;
    t13 = t8 & t11;
    a = t5 ^ t13
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 2 + 8]
    b ^= key[4 * 2 + 9]
    c ^= key[4 * 2 + 10]
    d ^= key[4 * 2 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 3 + 8]
    f ^= key[4 * 3 + 9]
    g ^= key[4 * 3 + 10]
    h ^= key[4 * 3 + 11]
    t1 = e ^ g;
    t2 = h ^ t1;
    t3 = e & t2;
    t4 = h ^ t3;
    t5 = f & t4;
    c = t2 ^ t5;
    t7 = e | c;
    t8 = f | h;
    t11 = e | h;
    t9 = t4 & t7;
    b = t8 ^ t9;
    t12 = f ^ t11;
    t13 = c ^ t9;
    t15 = t3 ^ t8;
    d = t12 ^ t13;
    t16 = g & t15;
    a = t12 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 4 + 8]
    b ^= key[4 * 4 + 9]
    c ^= key[4 * 4 + 10]
    d ^= key[4 * 4 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 5 + 8]
    f ^= key[4 * 5 + 9]
    g ^= key[4 * 5 + 10]
    h ^= key[4 * 5 + 11]
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = e ^ h;
    t4 = g ^ t1;
    t5 = t2 | t3;
    a = t4 ^ t5;
    t7 = h & a;
    t8 = t2 ^ a;
    t10 = t1 | a;
    b = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = f ^ t7;
    c = t11 ^ t12;
    t15 = b & t12;
    d = t14 ^ t15
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 6 + 8]
    b ^= key[4 * 6 + 9]
    c ^= key[4 * 6 + 10]
    d ^= key[4 * 6 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 7 + 8]
    f ^= key[4 * 7 + 9]
    g ^= key[4 * 7 + 10]
    h ^= key[4 * 7 + 11]
    t1 = (~g) % 0x100000000;
    t2 = f ^ g;
    t3 = f | t1;
    t4 = h ^ t3;
    t5 = e & t4;
    t7 = e ^ h;
    d = t2 ^ t5;
    t8 = f ^ t5;
    t9 = t2 | t8;
    t11 = h & t3;
    b = t7 ^ t9;
    t12 = t5 ^ b;
    t15 = t1 | t4;
    t13 = d & t12;
    c = t11 ^ t13;
    t16 = t12 ^ c;
    a = t15 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 8 + 8]
    b ^= key[4 * 8 + 9]
    c ^= key[4 * 8 + 10]
    d ^= key[4 * 8 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 9 + 8]
    f ^= key[4 * 9 + 9]
    g ^= key[4 * 9 + 10]
    h ^= key[4 * 9 + 11]
    t1 = (~e) % 0x100000000;
    t2 = f ^ t1;
    t3 = e | t2;
    t4 = h | t2;
    t5 = g ^ t3;
    c = h ^ t5;
    t7 = f ^ t4;
    t8 = t2 ^ c;
    t9 = t5 & t7;
    d = t8 ^ t9;
    t11 = t5 ^ t7;
    b = d ^ t11;
    t13 = t8 & t11;
    a = t5 ^ t13
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 10 + 8]
    b ^= key[4 * 10 + 9]
    c ^= key[4 * 10 + 10]
    d ^= key[4 * 10 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 11 + 8]
    f ^= key[4 * 11 + 9]
    g ^= key[4 * 11 + 10]
    h ^= key[4 * 11 + 11]
    t1 = e ^ g;
    t2 = h ^ t1;
    t3 = e & t2;
    t4 = h ^ t3;
    t5 = f & t4;
    c = t2 ^ t5;
    t7 = e | c;
    t8 = f | h;
    t11 = e | h;
    t9 = t4 & t7;
    b = t8 ^ t9;
    t12 = f ^ t11;
    t13 = c ^ t9;
    t15 = t3 ^ t8;
    d = t12 ^ t13;
    t16 = g & t15;
    a = t12 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 12 + 8]
    b ^= key[4 * 12 + 9]
    c ^= key[4 * 12 + 10]
    d ^= key[4 * 12 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 13 + 8]
    f ^= key[4 * 13 + 9]
    g ^= key[4 * 13 + 10]
    h ^= key[4 * 13 + 11]
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = e ^ h;
    t4 = g ^ t1;
    t5 = t2 | t3;
    a = t4 ^ t5;
    t7 = h & a;
    t8 = t2 ^ a;
    t10 = t1 | a;
    b = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = f ^ t7;
    c = t11 ^ t12;
    t15 = b & t12;
    d = t14 ^ t15
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 14 + 8]
    b ^= key[4 * 14 + 9]
    c ^= key[4 * 14 + 10]
    d ^= key[4 * 14 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 15 + 8]
    f ^= key[4 * 15 + 9]
    g ^= key[4 * 15 + 10]
    h ^= key[4 * 15 + 11]
    t1 = (~g) % 0x100000000;
    t2 = f ^ g;
    t3 = f | t1;
    t4 = h ^ t3;
    t5 = e & t4;
    t7 = e ^ h;
    d = t2 ^ t5;
    t8 = f ^ t5;
    t9 = t2 | t8;
    t11 = h & t3;
    b = t7 ^ t9;
    t12 = t5 ^ b;
    t15 = t1 | t4;
    t13 = d & t12;
    c = t11 ^ t13;
    t16 = t12 ^ c;
    a = t15 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 16 + 8]
    b ^= key[4 * 16 + 9]
    c ^= key[4 * 16 + 10]
    d ^= key[4 * 16 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 17 + 8]
    f ^= key[4 * 17 + 9]
    g ^= key[4 * 17 + 10]
    h ^= key[4 * 17 + 11]
    t1 = (~e) % 0x100000000;
    t2 = f ^ t1;
    t3 = e | t2;
    t4 = h | t2;
    t5 = g ^ t3;
    c = h ^ t5;
    t7 = f ^ t4;
    t8 = t2 ^ c;
    t9 = t5 & t7;
    d = t8 ^ t9;
    t11 = t5 ^ t7;
    b = d ^ t11;
    t13 = t8 & t11;
    a = t5 ^ t13
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 18 + 8]
    b ^= key[4 * 18 + 9]
    c ^= key[4 * 18 + 10]
    d ^= key[4 * 18 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 19 + 8]
    f ^= key[4 * 19 + 9]
    g ^= key[4 * 19 + 10]
    h ^= key[4 * 19 + 11]
    t1 = e ^ g;
    t2 = h ^ t1;
    t3 = e & t2;
    t4 = h ^ t3;
    t5 = f & t4;
    c = t2 ^ t5;
    t7 = e | c;
    t8 = f | h;
    t11 = e | h;
    t9 = t4 & t7;
    b = t8 ^ t9;
    t12 = f ^ t11;
    t13 = c ^ t9;
    t15 = t3 ^ t8;
    d = t12 ^ t13;
    t16 = g & t15;
    a = t12 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 20 + 8]
    b ^= key[4 * 20 + 9]
    c ^= key[4 * 20 + 10]
    d ^= key[4 * 20 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 21 + 8]
    f ^= key[4 * 21 + 9]
    g ^= key[4 * 21 + 10]
    h ^= key[4 * 21 + 11]
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = e ^ h;
    t4 = g ^ t1;
    t5 = t2 | t3;
    a = t4 ^ t5;
    t7 = h & a;
    t8 = t2 ^ a;
    t10 = t1 | a;
    b = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = f ^ t7;
    c = t11 ^ t12;
    t15 = b & t12;
    d = t14 ^ t15
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 22 + 8]
    b ^= key[4 * 22 + 9]
    c ^= key[4 * 22 + 10]
    d ^= key[4 * 22 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 23 + 8]
    f ^= key[4 * 23 + 9]
    g ^= key[4 * 23 + 10]
    h ^= key[4 * 23 + 11]
    t1 = (~g) % 0x100000000;
    t2 = f ^ g;
    t3 = f | t1;
    t4 = h ^ t3;
    t5 = e & t4;
    t7 = e ^ h;
    d = t2 ^ t5;
    t8 = f ^ t5;
    t9 = t2 | t8;
    t11 = h & t3;
    b = t7 ^ t9;
    t12 = t5 ^ b;
    t15 = t1 | t4;
    t13 = d & t12;
    c = t11 ^ t13;
    t16 = t12 ^ c;
    a = t15 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 24 + 8]
    b ^= key[4 * 24 + 9]
    c ^= key[4 * 24 + 10]
    d ^= key[4 * 24 + 11]
    t1 = a ^ d;
    t2 = a & d;
    t3 = c ^ t1;
    t6 = b & t1;
    t4 = b ^ t3;
    t10 = (~t3) % 0x100000000;
    h = t2 ^ t4;
    t7 = a ^ t6;
    t14 = (~t7) % 0x100000000;
    t8 = c | t7;
    t11 = t3 ^ t7;
    g = t4 ^ t8;
    t12 = h & t11;
    f = t10 ^ t12;
    e = t12 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 25 + 8]
    f ^= key[4 * 25 + 9]
    g ^= key[4 * 25 + 10]
    h ^= key[4 * 25 + 11]
    t1 = (~e) % 0x100000000;
    t2 = f ^ t1;
    t3 = e | t2;
    t4 = h | t2;
    t5 = g ^ t3;
    c = h ^ t5;
    t7 = f ^ t4;
    t8 = t2 ^ c;
    t9 = t5 & t7;
    d = t8 ^ t9;
    t11 = t5 ^ t7;
    b = d ^ t11;
    t13 = t8 & t11;
    a = t5 ^ t13
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 26 + 8]
    b ^= key[4 * 26 + 9]
    c ^= key[4 * 26 + 10]
    d ^= key[4 * 26 + 11]
    t1 = (~a) % 0x100000000;
    t2 = b ^ d;
    t3 = c & t1;
    t13 = d | t1;
    e = t2 ^ t3;
    t5 = c ^ t1;
    t6 = c ^ e;
    t7 = b & t6;
    t10 = e | t5;
    h = t5 ^ t7;
    t9 = d | t7;
    t11 = t9 & t10;
    t14 = t2 ^ h;
    g = a ^ t11;
    t15 = g ^ t13;
    f = t14 ^ t15
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 27 + 8]
    f ^= key[4 * 27 + 9]
    g ^= key[4 * 27 + 10]
    h ^= key[4 * 27 + 11]
    t1 = e ^ g;
    t2 = h ^ t1;
    t3 = e & t2;
    t4 = h ^ t3;
    t5 = f & t4;
    c = t2 ^ t5;
    t7 = e | c;
    t8 = f | h;
    t11 = e | h;
    t9 = t4 & t7;
    b = t8 ^ t9;
    t12 = f ^ t11;
    t13 = c ^ t9;
    t15 = t3 ^ t8;
    d = t12 ^ t13;
    t16 = g & t15;
    a = t12 ^ t16
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 28 + 8]
    b ^= key[4 * 28 + 9]
    c ^= key[4 * 28 + 10]
    d ^= key[4 * 28 + 11]
    t1 = a ^ d;
    t2 = d & t1;
    t3 = c ^ t2;
    t4 = b | t3;
    h = t1 ^ t4;
    t6 = (~b) % 0x100000000;
    t7 = t1 | t6;
    e = t3 ^ t7;
    t9 = a & e;
    t10 = t1 ^ t6;
    t11 = t4 & t10;
    g = t9 ^ t11;
    t13 = a ^ t3;
    t14 = t10 & g;
    f = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 29 + 8]
    f ^= key[4 * 29 + 9]
    g ^= key[4 * 29 + 10]
    h ^= key[4 * 29 + 11]
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = e ^ h;
    t4 = g ^ t1;
    t5 = t2 | t3;
    a = t4 ^ t5;
    t7 = h & a;
    t8 = t2 ^ a;
    t10 = t1 | a;
    b = t7 ^ t8;
    t11 = t2 | t7;
    t12 = t3 ^ t10;
    t14 = f ^ t7;
    c = t11 ^ t12;
    t15 = b & t12;
    d = t14 ^ t15
    a = rotl32(a, 13)
    c = rotl32(c, 3)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    d = rotl32(d, 7)
    b = rotl32(b, 1)
    a ^= b ^ d
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a = rotl32(a, 5)
    c = rotl32(c, 22)
    a ^= key[4 * 30 + 8]
    b ^= key[4 * 30 + 9]
    c ^= key[4 * 30 + 10]
    d ^= key[4 * 30 + 11]
    t1 = (~a) % 0x100000000;
    t2 = a ^ d;
    t3 = b ^ t2;
    t4 = t1 | t2;
    t5 = c ^ t4;
    f = b ^ t5;
    t13 = (~t5) % 0x100000000;
    t7 = t2 | f;
    t8 = d ^ t7;
    t9 = t5 & t8;
    g = t3 ^ t9;
    t11 = t5 ^ t8;
    e = g ^ t11;
    t14 = t3 & t11;
    h = t13 ^ t14
    e = rotl32(e, 13)
    g = rotl32(g, 3)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    h = rotl32(h, 7)
    f = rotl32(f, 1)
    e ^= f ^ h
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e = rotl32(e, 5)
    g = rotl32(g, 22)
    e ^= key[4 * 31 + 8]
    f ^= key[4 * 31 + 9]
    g ^= key[4 * 31 + 10]
    h ^= key[4 * 31 + 11]
    t1 = (~g) % 0x100000000;
    t2 = f ^ g;
    t3 = f | t1;
    t4 = h ^ t3;
    t5 = e & t4;
    t7 = e ^ h;
    d = t2 ^ t5;
    t8 = f ^ t5;
    t9 = t2 | t8;
    t11 = h & t3;
    b = t7 ^ t9;
    t12 = t5 ^ b;
    t15 = t1 | t4;
    t13 = d & t12;
    c = t11 ^ t13;
    t16 = t12 ^ c;
    a = t15 ^ t16
    a ^= key[4 * 32 + 8]
    b ^= key[4 * 32 + 9]
    c ^= key[4 * 32 + 10]
    d ^= key[4 * 32 + 11]
    if WORD_BIGENDIAN:
        a = byteswap32(a)
        b = byteswap32(b)
        c = byteswap32(c)
        d = byteswap32(d)
    in_blk[0] = a
    in_blk[1] = b
    in_blk[2] = c
    in_blk[3] = d


def decrypt(key, in_blk):
    # serpent_generate.py
    a = in_blk[0]
    b = in_blk[1]
    c = in_blk[2]
    d = in_blk[3]
    if WORD_BIGENDIAN:
        a = byteswap32(a)
        b = byteswap32(b)
        c = byteswap32(c)
        d = byteswap32(d)
    e = 0
    f = 0
    g = 0
    h = 0
    t1 = 0
    t2 = 0
    t3 = 0
    t4 = 0
    t5 = 0
    t6 = 0
    t7 = 0
    t8 = 0
    t9 = 0
    t10 = 0
    t11 = 0
    t12 = 0
    t13 = 0
    t14 = 0
    t15 = 0
    t16 = 0
    a ^= key[4 * 32 + 8]
    b ^= key[4 * 32 + 9]
    c ^= key[4 * 32 + 10]
    d ^= key[4 * 32 + 11]
    t1 = a & b;
    t2 = a | b;
    t3 = c | t1;
    t4 = d & t2;
    h = t3 ^ t4;
    t6 = (~d) % 0x100000000;
    t7 = b ^ t4;
    t8 = h ^ t6;
    t11 = c ^ t7;
    t9 = t7 | t8;
    f = a ^ t9;
    t12 = d | f;
    e = t11 ^ t12;
    t14 = a & h;
    t15 = t3 ^ f;
    t16 = e ^ t14;
    g = t15 ^ t16
    e ^= key[4 * 31 + 8]
    f ^= key[4 * 31 + 9]
    g ^= key[4 * 31 + 10]
    h ^= key[4 * 31 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = g ^ t2;
    t4 = g | t1;
    t5 = h ^ t4;
    t13 = h & t1;
    b = t3 ^ t5;
    t7 = t3 & t5;
    t8 = t2 ^ t7;
    t9 = f | t8;
    d = t5 ^ t9;
    t11 = f | d;
    a = t8 ^ t11;
    t14 = t3 ^ t11;
    c = t13 ^ t14
    a ^= key[4 * 30 + 8]
    b ^= key[4 * 30 + 9]
    c ^= key[4 * 30 + 10]
    d ^= key[4 * 30 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = (~c) % 0x100000000;
    t2 = b & t1;
    t3 = d ^ t2;
    t4 = a & t3;
    t5 = b ^ t1;
    h = t4 ^ t5;
    t7 = b | h;
    t8 = a & t7;
    f = t3 ^ t8;
    t10 = a | d;
    t11 = t1 ^ t7;
    e = t10 ^ t11;
    t13 = a ^ c;
    t14 = b & t10;
    t15 = t4 | t13;
    g = t14 ^ t15
    e ^= key[4 * 29 + 8]
    f ^= key[4 * 29 + 9]
    g ^= key[4 * 29 + 10]
    h ^= key[4 * 29 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = g ^ h;
    t2 = g | h;
    t3 = f ^ t2;
    t4 = e & t3;
    b = t1 ^ t4;
    t6 = e ^ h;
    t7 = f | h;
    t8 = t6 & t7;
    d = t3 ^ t8;
    t10 = (~e) % 0x100000000;
    t11 = g ^ d;
    t12 = t10 | t11;
    a = t3 ^ t12;
    t14 = g | t4;
    t15 = t7 ^ t14;
    t16 = d | t10;
    c = t15 ^ t16
    a ^= key[4 * 28 + 8]
    b ^= key[4 * 28 + 9]
    c ^= key[4 * 28 + 10]
    d ^= key[4 * 28 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)

    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = b ^ c;
    t2 = b | c;
    t3 = a ^ c;
    t7 = a ^ d;
    t4 = t2 ^ t3;
    t5 = d | t4;
    t9 = t2 ^ t7;
    e = t1 ^ t5;
    t8 = t1 | t5;
    t11 = a & t4;
    g = t8 ^ t9;
    t12 = e | t9;
    f = t11 ^ t12;
    t14 = a & g;
    t15 = t2 ^ t14;
    t16 = e & t15;
    h = t4 ^ t16
    e ^= key[4 * 27 + 8]
    f ^= key[4 * 27 + 9]
    g ^= key[4 * 27 + 10]
    h ^= key[4 * 27 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = f ^ h;
    t2 = (~t1) % 0x100000000;
    t3 = e ^ g;
    t4 = g ^ t1;
    t7 = e | t2;
    t5 = f & t4;
    t8 = h ^ t7;
    t11 = (~t4) % 0x100000000;
    a = t3 ^ t5;
    t9 = t3 | t8;
    t14 = h & t11;
    d = t1 ^ t9;
    t12 = a | d;
    b = t11 ^ t12;
    t15 = t3 ^ t12;
    c = t14 ^ t15
    a ^= key[4 * 26 + 8]
    b ^= key[4 * 26 + 9]
    c ^= key[4 * 26 + 10]
    d ^= key[4 * 26 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a ^ d;
    t2 = a & b;
    t3 = b ^ c;
    t4 = a ^ t3;
    t5 = b | d;
    t7 = c | t1;
    h = t4 ^ t5;
    t8 = b ^ t7;
    t11 = (~t2) % 0x100000000;
    t9 = t4 & t8;
    f = t1 ^ t9;
    t13 = t9 ^ t11;
    t12 = h & f;
    g = t12 ^ t13;
    t15 = a & d;
    t16 = c ^ t13;
    e = t15 ^ t16
    e ^= key[4 * 25 + 8]
    f ^= key[4 * 25 + 9]
    g ^= key[4 * 25 + 10]
    h ^= key[4 * 25 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000
    t2 = e ^ f
    t3 = t1 | t2
    t4 = h ^ t3
    t7 = h & t2
    t5 = g ^ t4
    t8 = t1 ^ t7
    c = t2 ^ t5
    t11 = e & t4
    t9 = c & t8
    t14 = t5 ^ t8
    b = t4 ^ t9
    t12 = t5 | b
    d = t11 ^ t12
    a = d ^ t14
    a ^= key[4 * 24 + 8]
    b ^= key[4 * 24 + 9]
    c ^= key[4 * 24 + 10]
    d ^= key[4 * 24 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a & b;
    t2 = a | b;
    t3 = c | t1;
    t4 = d & t2;
    h = t3 ^ t4;
    t6 = (~d) % 0x100000000;
    t7 = b ^ t4;
    t8 = h ^ t6;
    t11 = c ^ t7;
    t9 = t7 | t8;
    f = a ^ t9;
    t12 = d | f;
    e = t11 ^ t12;
    t14 = a & h;
    t15 = t3 ^ f;
    t16 = e ^ t14;
    g = t15 ^ t16
    e ^= key[4 * 23 + 8]
    f ^= key[4 * 23 + 9]
    g ^= key[4 * 23 + 10]
    h ^= key[4 * 23 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = g ^ t2;
    t4 = g | t1;
    t5 = h ^ t4;
    t13 = h & t1;
    b = t3 ^ t5;
    t7 = t3 & t5;
    t8 = t2 ^ t7;
    t9 = f | t8;
    d = t5 ^ t9;
    t11 = f | d;
    a = t8 ^ t11;
    t14 = t3 ^ t11;
    c = t13 ^ t14
    a ^= key[4 * 22 + 8]
    b ^= key[4 * 22 + 9]
    c ^= key[4 * 22 + 10]
    d ^= key[4 * 22 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = (~c) % 0x100000000;
    t2 = b & t1;
    t3 = d ^ t2;
    t4 = a & t3;
    t5 = b ^ t1;
    h = t4 ^ t5;
    t7 = b | h;
    t8 = a & t7;
    f = t3 ^ t8;
    t10 = a | d;
    t11 = t1 ^ t7;
    e = t10 ^ t11;
    t13 = a ^ c;
    t14 = b & t10;
    t15 = t4 | t13;
    g = t14 ^ t15
    e ^= key[4 * 21 + 8]
    f ^= key[4 * 21 + 9]
    g ^= key[4 * 21 + 10]
    h ^= key[4 * 21 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = g ^ h;
    t2 = g | h;
    t3 = f ^ t2;
    t4 = e & t3;
    b = t1 ^ t4;
    t6 = e ^ h;
    t7 = f | h;
    t8 = t6 & t7;
    d = t3 ^ t8;
    t10 = (~e) % 0x100000000;
    t11 = g ^ d;
    t12 = t10 | t11;
    a = t3 ^ t12;
    t14 = g | t4;
    t15 = t7 ^ t14;
    t16 = d | t10;
    c = t15 ^ t16
    a ^= key[4 * 20 + 8]
    b ^= key[4 * 20 + 9]
    c ^= key[4 * 20 + 10]
    d ^= key[4 * 20 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = b ^ c;
    t2 = b | c;
    t3 = a ^ c;
    t7 = a ^ d;
    t4 = t2 ^ t3;
    t5 = d | t4;
    t9 = t2 ^ t7;
    e = t1 ^ t5;
    t8 = t1 | t5;
    t11 = a & t4;
    g = t8 ^ t9;
    t12 = e | t9;
    f = t11 ^ t12;
    t14 = a & g;
    t15 = t2 ^ t14;
    t16 = e & t15;
    h = t4 ^ t16
    e ^= key[4 * 19 + 8]
    f ^= key[4 * 19 + 9]
    g ^= key[4 * 19 + 10]
    h ^= key[4 * 19 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = f ^ h;
    t2 = (~t1) % 0x100000000;
    t3 = e ^ g;
    t4 = g ^ t1;
    t7 = e | t2;
    t5 = f & t4;
    t8 = h ^ t7;
    t11 = (~t4) % 0x100000000;
    a = t3 ^ t5;
    t9 = t3 | t8;
    t14 = h & t11;
    d = t1 ^ t9;
    t12 = a | d;
    b = t11 ^ t12;
    t15 = t3 ^ t12;
    c = t14 ^ t15
    a ^= key[4 * 18 + 8]
    b ^= key[4 * 18 + 9]
    c ^= key[4 * 18 + 10]
    d ^= key[4 * 18 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a ^ d;
    t2 = a & b;
    t3 = b ^ c;
    t4 = a ^ t3;
    t5 = b | d;
    t7 = c | t1;
    h = t4 ^ t5;
    t8 = b ^ t7;
    t11 = (~t2) % 0x100000000;
    t9 = t4 & t8;
    f = t1 ^ t9;
    t13 = t9 ^ t11;
    t12 = h & f;
    g = t12 ^ t13;
    t15 = a & d;
    t16 = c ^ t13;
    e = t15 ^ t16
    e ^= key[4 * 17 + 8]
    f ^= key[4 * 17 + 9]
    g ^= key[4 * 17 + 10]
    h ^= key[4 * 17 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000
    t2 = e ^ f
    t3 = t1 | t2
    t4 = h ^ t3
    t7 = h & t2
    t5 = g ^ t4
    t8 = t1 ^ t7
    c = t2 ^ t5
    t11 = e & t4
    t9 = c & t8
    t14 = t5 ^ t8
    b = t4 ^ t9
    t12 = t5 | b
    d = t11 ^ t12
    a = d ^ t14
    a ^= key[4 * 16 + 8]
    b ^= key[4 * 16 + 9]
    c ^= key[4 * 16 + 10]
    d ^= key[4 * 16 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a & b;
    t2 = a | b;
    t3 = c | t1;
    t4 = d & t2;
    h = t3 ^ t4;
    t6 = (~d) % 0x100000000;
    t7 = b ^ t4;
    t8 = h ^ t6;
    t11 = c ^ t7;
    t9 = t7 | t8;
    f = a ^ t9;
    t12 = d | f;
    e = t11 ^ t12;
    t14 = a & h;
    t15 = t3 ^ f;
    t16 = e ^ t14;
    g = t15 ^ t16
    e ^= key[4 * 15 + 8]
    f ^= key[4 * 15 + 9]
    g ^= key[4 * 15 + 10]
    h ^= key[4 * 15 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = g ^ t2;
    t4 = g | t1;
    t5 = h ^ t4;
    t13 = h & t1;
    b = t3 ^ t5;
    t7 = t3 & t5;
    t8 = t2 ^ t7;
    t9 = f | t8;
    d = t5 ^ t9;
    t11 = f | d;
    a = t8 ^ t11;
    t14 = t3 ^ t11;
    c = t13 ^ t14
    a ^= key[4 * 14 + 8]
    b ^= key[4 * 14 + 9]
    c ^= key[4 * 14 + 10]
    d ^= key[4 * 14 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = (~c) % 0x100000000;
    t2 = b & t1;
    t3 = d ^ t2;
    t4 = a & t3;
    t5 = b ^ t1;
    h = t4 ^ t5;
    t7 = b | h;
    t8 = a & t7;
    f = t3 ^ t8;
    t10 = a | d;
    t11 = t1 ^ t7;
    e = t10 ^ t11;
    t13 = a ^ c;
    t14 = b & t10;
    t15 = t4 | t13;
    g = t14 ^ t15
    e ^= key[4 * 13 + 8]
    f ^= key[4 * 13 + 9]
    g ^= key[4 * 13 + 10]
    h ^= key[4 * 13 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = g ^ h;
    t2 = g | h;
    t3 = f ^ t2;
    t4 = e & t3;
    b = t1 ^ t4;
    t6 = e ^ h;
    t7 = f | h;
    t8 = t6 & t7;
    d = t3 ^ t8;
    t10 = (~e) % 0x100000000;
    t11 = g ^ d;
    t12 = t10 | t11;
    a = t3 ^ t12;
    t14 = g | t4;
    t15 = t7 ^ t14;
    t16 = d | t10;
    c = t15 ^ t16
    a ^= key[4 * 12 + 8]
    b ^= key[4 * 12 + 9]
    c ^= key[4 * 12 + 10]
    d ^= key[4 * 12 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = b ^ c;
    t2 = b | c;
    t3 = a ^ c;
    t7 = a ^ d;
    t4 = t2 ^ t3;
    t5 = d | t4;
    t9 = t2 ^ t7;
    e = t1 ^ t5;
    t8 = t1 | t5;
    t11 = a & t4;
    g = t8 ^ t9;
    t12 = e | t9;
    f = t11 ^ t12;
    t14 = a & g;
    t15 = t2 ^ t14;
    t16 = e & t15;
    h = t4 ^ t16
    e ^= key[4 * 11 + 8]
    f ^= key[4 * 11 + 9]
    g ^= key[4 * 11 + 10]
    h ^= key[4 * 11 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = f ^ h;
    t2 = (~t1) % 0x100000000;
    t3 = e ^ g;
    t4 = g ^ t1;
    t7 = e | t2;
    t5 = f & t4;
    t8 = h ^ t7;
    t11 = (~t4) % 0x100000000;
    a = t3 ^ t5;
    t9 = t3 | t8;
    t14 = h & t11;
    d = t1 ^ t9;
    t12 = a | d;
    b = t11 ^ t12;
    t15 = t3 ^ t12;
    c = t14 ^ t15
    a ^= key[4 * 10 + 8]
    b ^= key[4 * 10 + 9]
    c ^= key[4 * 10 + 10]
    d ^= key[4 * 10 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a ^ d;
    t2 = a & b;
    t3 = b ^ c;
    t4 = a ^ t3;
    t5 = b | d;
    t7 = c | t1;
    h = t4 ^ t5;
    t8 = b ^ t7;
    t11 = (~t2) % 0x100000000;
    t9 = t4 & t8;
    f = t1 ^ t9;
    t13 = t9 ^ t11;
    t12 = h & f;
    g = t12 ^ t13;
    t15 = a & d;
    t16 = c ^ t13;
    e = t15 ^ t16
    e ^= key[4 * 9 + 8]
    f ^= key[4 * 9 + 9]
    g ^= key[4 * 9 + 10]
    h ^= key[4 * 9 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000
    t2 = e ^ f
    t3 = t1 | t2
    t4 = h ^ t3
    t7 = h & t2
    t5 = g ^ t4
    t8 = t1 ^ t7
    c = t2 ^ t5
    t11 = e & t4
    t9 = c & t8
    t14 = t5 ^ t8
    b = t4 ^ t9
    t12 = t5 | b
    d = t11 ^ t12
    a = d ^ t14
    a ^= key[4 * 8 + 8]
    b ^= key[4 * 8 + 9]
    c ^= key[4 * 8 + 10]
    d ^= key[4 * 8 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a & b;
    t2 = a | b;
    t3 = c | t1;
    t4 = d & t2;
    h = t3 ^ t4;
    t6 = (~d) % 0x100000000;
    t7 = b ^ t4;
    t8 = h ^ t6;
    t11 = c ^ t7;
    t9 = t7 | t8;
    f = a ^ t9;
    t12 = d | f;
    e = t11 ^ t12;
    t14 = a & h;
    t15 = t3 ^ f;
    t16 = e ^ t14;
    g = t15 ^ t16
    e ^= key[4 * 7 + 8]
    f ^= key[4 * 7 + 9]
    g ^= key[4 * 7 + 10]
    h ^= key[4 * 7 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000;
    t2 = e ^ f;
    t3 = g ^ t2;
    t4 = g | t1;
    t5 = h ^ t4;
    t13 = h & t1;
    b = t3 ^ t5;
    t7 = t3 & t5;
    t8 = t2 ^ t7;
    t9 = f | t8;
    d = t5 ^ t9;
    t11 = f | d;
    a = t8 ^ t11;
    t14 = t3 ^ t11;
    c = t13 ^ t14
    a ^= key[4 * 6 + 8]
    b ^= key[4 * 6 + 9]
    c ^= key[4 * 6 + 10]
    d ^= key[4 * 6 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = (~c) % 0x100000000;
    t2 = b & t1;
    t3 = d ^ t2;
    t4 = a & t3;
    t5 = b ^ t1;
    h = t4 ^ t5;
    t7 = b | h;
    t8 = a & t7;
    f = t3 ^ t8;
    t10 = a | d;
    t11 = t1 ^ t7;
    e = t10 ^ t11;
    t13 = a ^ c;
    t14 = b & t10;
    t15 = t4 | t13;
    g = t14 ^ t15
    e ^= key[4 * 5 + 8]
    f ^= key[4 * 5 + 9]
    g ^= key[4 * 5 + 10]
    h ^= key[4 * 5 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = g ^ h;
    t2 = g | h;
    t3 = f ^ t2;
    t4 = e & t3;
    b = t1 ^ t4;
    t6 = e ^ h;
    t7 = f | h;
    t8 = t6 & t7;
    d = t3 ^ t8;
    t10 = (~e) % 0x100000000;
    t11 = g ^ d;
    t12 = t10 | t11;
    a = t3 ^ t12;
    t14 = g | t4;
    t15 = t7 ^ t14;
    t16 = d | t10;
    c = t15 ^ t16
    a ^= key[4 * 4 + 8]
    b ^= key[4 * 4 + 9]
    c ^= key[4 * 4 + 10]
    d ^= key[4 * 4 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = b ^ c;
    t2 = b | c;
    t3 = a ^ c;
    t7 = a ^ d;
    t4 = t2 ^ t3;
    t5 = d | t4;
    t9 = t2 ^ t7;
    e = t1 ^ t5;
    t8 = t1 | t5;
    t11 = a & t4;
    g = t8 ^ t9;
    t12 = e | t9;
    f = t11 ^ t12;
    t14 = a & g;
    t15 = t2 ^ t14;
    t16 = e & t15;
    h = t4 ^ t16
    e ^= key[4 * 3 + 8]
    f ^= key[4 * 3 + 9]
    g ^= key[4 * 3 + 10]
    h ^= key[4 * 3 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = f ^ h;
    t2 = (~t1) % 0x100000000;
    t3 = e ^ g;
    t4 = g ^ t1;
    t7 = e | t2;
    t5 = f & t4;
    t8 = h ^ t7;
    t11 = (~t4) % 0x100000000;
    a = t3 ^ t5;
    t9 = t3 | t8;
    t14 = h & t11;
    d = t1 ^ t9;
    t12 = a | d;
    b = t11 ^ t12;
    t15 = t3 ^ t12;
    c = t14 ^ t15
    a ^= key[4 * 2 + 8]
    b ^= key[4 * 2 + 9]
    c ^= key[4 * 2 + 10]
    d ^= key[4 * 2 + 11]
    c = rotr32(c, 22)
    a = rotr32(a, 5)
    c ^= d ^ ((b << 7) & 0xFFFFFFFF)
    a ^= b ^ d
    d = rotr32(d, 7)
    b = rotr32(b, 1)
    d ^= c ^ ((a << 3) & 0xFFFFFFFF)
    b ^= a ^ c
    c = rotr32(c, 3)
    a = rotr32(a, 13)
    t1 = a ^ d;
    t2 = a & b;
    t3 = b ^ c;
    t4 = a ^ t3;
    t5 = b | d;
    t7 = c | t1;
    h = t4 ^ t5;
    t8 = b ^ t7;
    t11 = (~t2) % 0x100000000;
    t9 = t4 & t8;
    f = t1 ^ t9;
    t13 = t9 ^ t11;
    t12 = h & f;
    g = t12 ^ t13;
    t15 = a & d;
    t16 = c ^ t13;
    e = t15 ^ t16
    e ^= key[4 * 1 + 8]
    f ^= key[4 * 1 + 9]
    g ^= key[4 * 1 + 10]
    h ^= key[4 * 1 + 11]
    g = rotr32(g, 22)
    e = rotr32(e, 5)
    g ^= h ^ ((f << 7) & 0xFFFFFFFF)
    e ^= f ^ h
    h = rotr32(h, 7)
    f = rotr32(f, 1)
    h ^= g ^ ((e << 3) & 0xFFFFFFFF)
    f ^= e ^ g
    g = rotr32(g, 3)
    e = rotr32(e, 13)
    t1 = (~e) % 0x100000000
    t2 = e ^ f
    t3 = t1 | t2
    t4 = h ^ t3
    t7 = h & t2
    t5 = g ^ t4
    t8 = t1 ^ t7
    c = t2 ^ t5
    t11 = e & t4
    t9 = c & t8
    t14 = t5 ^ t8
    b = t4 ^ t9
    t12 = t5 | b
    d = t11 ^ t12
    a = d ^ t14
    a ^= key[4 * 0 + 8]
    b ^= key[4 * 0 + 9]
    c ^= key[4 * 0 + 10]
    d ^= key[4 * 0 + 11]
    if WORD_BIGENDIAN:
        a = byteswap32(a)
        b = byteswap32(b)
        c = byteswap32(c)
        d = byteswap32(d)
    in_blk[0] = a
    in_blk[1] = b
    in_blk[2] = c
    in_blk[3] = d


# CBC Encrypt - Jason Reaves
def serpent_cbc_encrypt(key, data, iv=b'\x00' * 16):
    out = b""
    last = iv
    for i in range((len(data) // 16)):
        temp = data[i * 16:(i + 1) * 16]
        to_encode = b""
        for j in range(4):
            temp1 = struct.unpack_from('<I', temp[j * 4:])[0]
            temp2 = struct.unpack_from('<I', last[j * 4:])[0]
            to_encode += struct.pack('<I', ((temp1 ^ temp2) & 0xffffffff))
        last = Serpent(key).encrypt(to_encode)
        out += last
    # print(binascii.hexlify(Serpent(key).encrypt(data)))
    return out


# CBC Decrypt - Jason Reaves
def serpent_cbc_decrypt(key, data, iv=b'\x00' * 16):
    out2 = b""
    last = iv
    for i in range((len(data) // 16)):
        temp = Serpent(key).decrypt(data[i * 16:(i + 1) * 16])
        to_decode = b""
        for j in range(4):
            temp1 = struct.unpack_from('<I', temp[j * 4:])[0]
            temp2 = struct.unpack_from('<I', last[j * 4:])[0]
            to_decode += struct.pack('<I', ((temp1 ^ temp2) & 0xffffffff))
        out2 += to_decode
        last = data[i * 16:(i + 1) * 16]
    return out2


def PKCS7_padding(data, num):
    pad = num - (len(data) % num)
    return data + bytes([pad] * pad)


def PKCS7_unpadding(data):
    return data[:-data[-1]]


import base64


def serpent_encrypt(
        key: bytes,
        plaintext: bytes,
        iv=b'\x00' * 16,
        mode='cbc',
        enfunc=base64.b64encode,
):
    block_size = 16
    if mode == 'cbc':
        plaintext = PKCS7_padding(plaintext, block_size)
        return enfunc(serpent_cbc_encrypt(key, plaintext, iv))
    elif mode == 'ecb':
        plaintext = PKCS7_padding(plaintext, block_size)
        ret = b''
        for i in range(0, len(plaintext), block_size):
            ret += Serpent(key).encrypt(plaintext[i:i + block_size])
        return enfunc(ret)


def serpent_decrypt(
        key: bytes,
        plaintext: bytes,
        iv=b'\x00' * 16,
        mode='cbc',
        defunc=base64.b64decode,
):
    if mode == 'cbc':
        plaintext = defunc(plaintext)
        return PKCS7_unpadding(serpent_cbc_decrypt(key, plaintext, iv))
    elif mode == 'ecb':
        plaintext = defunc(plaintext)
        ret = b''
        for i in range(0, len(plaintext), block_size):
            ret += Serpent(key).decrypt(plaintext[i:i + block_size])
        return PKCS7_unpadding(ret)


if __name__ == '__main__':
    key = b'asdfasdfasdfasdf'  # 4 的倍数，同时长度需要小于等于32
    plaintext = b'asdfasdfasdfasdff'  # 如无pkcs处理，则必须 16 的倍数
    iv = b'asdfasdfasdfasdf'

    s = serpent_encrypt(key, plaintext, iv=iv, mode='cbc')
    print(s)
    s = serpent_decrypt(key, s, iv=iv, mode='cbc')
    print(s)

    s = serpent_encrypt(key, plaintext, iv=None, mode='ecb')
    print(s)
    s = serpent_decrypt(key, s, iv=None, mode='ecb')
    print(s)
